#include "Socket.h"
#include "Client.h"

Client::Client(int mode, int port, char *ip_addr, int timeout) : Socket(mode, port, ip_addr)
{
    ser_addr = NULL;
    this->skf_ = -1;
    this->setIP(ip_addr, timeout);
}

Client::~Client()
{
}

int Client::sendMsg(char *buff, int length)
{
    return this->sendMSG(this->skf_, buff, length);
}

int Client::receiveMsg()
{
    return this->receiveMSG(this->skf_, BUFFER_SIZE);
}

/**
 * @Author: 王占坤
 * @Description: 在skf上创建一个到serv_addr的连接
 * @Param: socketfd skf, 需要创建连接的socket句柄
 * @Param: struct sockaddr* serv_addr 连接的目标地址
 * @Param: int addr_len 目标地址大小
 * @Return: 成功返回0，否则返回-1
 * @Throw: 
 */
int Client::createConnection(struct sockaddr *serv_addr, size_t addr_len, int time)
{
    int ret = 0;
    if (time != 0)
    {
        struct timeval timeout;
        timeout.tv_sec = time / 1000;
        timeout.tv_usec = time * 1000 - timeout.tv_sec * 1000000;
        socklen_t len = sizeof(timeout);
        ret = setsockopt(skf_, SOL_SOCKET, SO_SNDTIMEO, &timeout, len);
        assert(ret != -1);
        ret = connect(skf_, serv_addr, addr_len);
        if (ret == -1)
        {
            if (errno == EINPROGRESS)
            {
                printf("connecting timeout!\n");
            }
            else
            {
                perror("connect");
                printf("create connection error: %s(errno: %d)\n", strerror(errno), errno);
            }
        }
    }
    else
    {
        ret = connect(skf_, serv_addr, addr_len);
        if (ret == -1)
        {
            perror("connect");
            printf("create connection error: %s(errno: %d)\n", strerror(errno), errno);
        }
    }
    return ret;
}

void Client::setIP(char *ip_addr, int timeout)
{
    if (ip_addr == NULL)
        return;
    strcpy(this->ip_, ip_addr);
    if (this->skf_ != -1)
        close(this->skf_);

    this->skf_ = createSocket();
    printf("Created socket %d\n", this->skf_);

    ser_addr = (struct sockaddr_in *)malloc(sizeof(struct sockaddr_in));
    initialzeSocketaddr(ser_addr, this->ip_);
    printf("initialzeSocketaddr successfully\n");

    int ret = -1;
    for (size_t i = 0; i < 20; i++)
    {
        ret = createConnection((struct sockaddr *)this->ser_addr, sizeof(struct sockaddr), timeout);
        if (ret == 0)
            break;
        usleep(5000000); //暂停连接500ms
    }

    if (ret == 0)
    {
        printf("connection established!\n");
    }
    else
    {
        printf("connection failed after 10 tries!\n");
        printf("please check your server is running or your network is up.\n");
    }
}
